package ThreadTest;

import java.util.ArrayList;
import java.util.List;

/*
1.使用wait方法和notify方法实现“生产者和消费者模式”
2.什么是“生产者和消费者模式”？
    生产线程负责生产，消费线程负责消费
    生产线程和消费线程要达到均衡
    这是一直特殊的业务需求，在这种特殊的情况下需要使用wait方法和notify方法
3.wait和notify方法不是线程对象的方法，是普通java对象都有的方法
4.wait方法和notify方法建立在线程同步的基础上，因为多线程要同时操作一个仓库，有线程安全的问题
5.wait方法作用:o.wait()让正在o对象上活动的线程t进入等待状态，并且释放掉t线程之前占有的o对象的锁
6.notify方法作用:o.notify()让正在o对象上等待的线程唤醒，只是通知，不会释放o对象上之前占有的锁
7.模拟一个这样的需求
    仓库采用List集合
 */
public class ThreadTest9 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        MyProduct myProduct = new MyProduct(list);
        Thread t1 = new Thread(myProduct);
        t1.setName("t1");
        MyConsume myConsume = new MyConsume(list);
        Thread c1 = new Thread(myConsume);
        c1.setName("c1");
        t1.start();
        c1.start();
    }
}

//创建生产线程
class MyProduct implements Runnable{
    ArrayList<Integer> arrayList;
    public MyProduct(ArrayList<Integer> arraylist) {
        this.arrayList = arraylist;
    }
    @Override
    public void run() {
        while(true){
            synchronized (arrayList){
                if(arrayList.size() > 10){
                    try {
                        //仓库有10件以上，生产线程进入等待
                        arrayList.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //当还没生产出10件货物时，继续生产
                }else if(arrayList.size() < 10){
                    arrayList.add(1);
                    System.out.println(Thread.currentThread().getName()+"生产了一件物品");
                }else {
                    //10件货物时，唤醒消费线程
                    arrayList.notify();
                }
            }
        }
    }
}
class MyConsume implements Runnable{
    ArrayList<Integer> arrayList;
    public MyConsume(ArrayList<Integer> arraylist) {
        this.arrayList = arraylist;
    }
    @Override
    public void run() {
       while(true){
           synchronized (arrayList){
               if(arrayList.size() == 0){
                   try {
                       //仓库没货了，消费线程进入等待
                       arrayList.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }else {
                   //有货物，继续卖出
                   arrayList.remove(arrayList.size() - 1);
                   System.out.println(Thread.currentThread().getName() + "消费了一件物品");
                   arrayList.notify();
               }
           }
       }
    }
}